//
// 栈
// Created by 麻再挺 on 2021/12/7.
//
#include "stack.h"

/**
 * 初始化栈
 */
Status Init_Stack(Stack *stack) {
    // 构造空栈
    stack->base = (SElemType *) malloc(STACK_INIT_SIZE * sizeof(SElemType));
    // 存储分配失败
    if (!stack->base) exit(OVERFLOW);
    // 初始化时栈底就是栈顶
    stack->top = stack->base;
    // 设置栈的大小
    stack->stack_size = STACK_INIT_SIZE;
    return OK;
}

/**
 * 销毁栈
 * @param stack 栈
 * @return
 */
Status Destroy_Stack(Stack *stack) {
    free(stack->base);
    stack->base = NULL;
    stack->top = NULL;
    stack->stack_size = 0;
    return OK;
}

/**
 * 清空栈
 * @param stack 栈
 * @return
 */
Status Clear_Stack(Stack *stack) {
    stack->top = stack->base;
    return OK;
}

/**
 * 是否为空栈
 * @param stack 栈
 * @return
 */
Status Stack_Empty(Stack *stack) {
    if (stack->top == stack->base) return TRUE;
    return FALSE;
}

/**
 * 栈长度
 * @param stack 栈
 * @return
 */
int Stack_Length(Stack *stack) {
    return (int)(stack->top - stack->base);
}

/**
 * 获取栈顶元素
 * 若栈顶不空, 则返回栈顶的元素,并返回 OK; 否则返回 ERROR
 * @param stack 栈
 * @param elem 元素
 */
Status Stack_GetTop(Stack *stack, SElemType *elem) {
    if (Stack_Empty(stack)) return ERROR;
    // 取当前元素, 位置减 1
    *elem = *(stack->top - 1);
    return OK;
}

/**
 * 入栈
 * 插入的元素为新的栈顶元素
 * @param stack 栈
 * @param elem 元素
 */
Status Stack_Push(Stack *stack, SElemType elem) {
    // 如果栈满了, 则扩容
    if (stack->top - stack->base >= stack->stack_size) {
        // 追加空间
        stack->base = (SElemType *)realloc(stack->base, (stack->stack_size + STACK_INCREMENT) * sizeof(SElemType));
        // 分配失败
        if (!stack->base) exit(OVERFLOW);
        // 赋值栈顶位置
        stack->top = stack->base + stack->stack_size;
        stack->stack_size += STACK_INCREMENT;
    }
    *stack->top++ = elem;
    return OK;
}

/**
 * 出栈
 * 如果栈顶不为空, 则删除栈顶元素, 并返回OK; 否则返回 ERROR.
 * @param stack 栈
 * @param elem 元素
 */
Status Stack_Pop(Stack *stack, SElemType *elem) {
    if (stack->top == stack->base) return ERROR;
    // 取栈顶元素
    // 取栈顶指针, --是为了拿到最顶部元素
    *elem = *(--stack->top);
    return OK;
}

/**
 * 打印站数据
 * @param stack
 */
void Stack_Print(Stack *stack) {
    // 获取栈长度
    int length = Stack_Length(stack);
    SElemType *elemType = (SElemType*) stack->base;
    for (int i = 0; i < length; ++i) {
        printf("%d", (int) *(elemType + i));
        if (i < length - 1) {
            printf(", ");
        }
    }
    printf("\n");
}














